#ifndef XABSTRACTSYNTAXTREEBUILDER_H
#define XABSTRACTSYNTAXTREEBUILDER_H
#include <stack>
#include <xscript/xlexer.h>
#include <xscript/xnameholder.h>
#include <xscript/xabstractsyntaxtree.h>
#include <xscript/xabstractsyntaxtreevisitor.h>
#include <xscript/xscriptexecutor.h>

class XAbstractSyntaxTreeCreator : public XNameHolder {
  public:
    virtual ~XAbstractSyntaxTreeCreator() = default;
  public:
    virtual bool isMatched(const XTokenBlock& tokens, uint32_t row, uint32_t col);
    virtual std::shared_ptr<XAbstractSyntaxTree> create(const XTokenBlock& tokens, uint32_t row, uint32_t col, std::shared_ptr<XAbstractSyntaxTreeBuilder> builder) {
        return nullptr;
    }
  public:
    uint32_t getSkipToRow()const {return skipToRow;}
    uint32_t getSkipToCol()const {return skipToCol;}
  protected:
    uint32_t skipToRow = 0;
    uint32_t skipToCol = 0;
};

class XAbstractSyntaxTreeBuilder : public XAbstractSyntaxTreeCreator, public XAbstractSyntaxTreeVisitor, public std::enable_shared_from_this<XAbstractSyntaxTreeBuilder> {
  public:
    XAbstractSyntaxTreeBuilder();
  public:
    void registerCreate(std::shared_ptr<XAbstractSyntaxTreeCreator> creator) {
        if (creator)
            creators.push_back(creator);
    }
    std::shared_ptr<XAbstractSyntaxTree> build(const XTokenBlock& tokens);
  public:
    void onReceivedPunctuatorOpenBrace(std::shared_ptr<XAbstractSyntaxTree> tree);
    void onReceivedPunctuatorCloseBrace(std::shared_ptr<XAbstractSyntaxTree> tree);

    void onReceivedPunctuatorOpenParenthesis(std::shared_ptr<XAbstractSyntaxTree> tree);
    void onReceivedPunctuatorCloseParenthesis(std::shared_ptr<XAbstractSyntaxTree> tree);

    void onReceivedPunctuatorOpenBracket(std::shared_ptr<XAbstractSyntaxTree> tree);
    void onReceivedPunctuatorCloseBracket(std::shared_ptr<XAbstractSyntaxTree> tree);
  private:
    std::vector<std::shared_ptr<XAbstractSyntaxTreeCreator>> creators;
    std::stack<std::shared_ptr<XAbstractSyntaxTree>> stack;
    bool added = false;
};

#endif // XABSTRACTSYNTAXTREEBUILDER_H
